using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
using TheLogWatcher.Properties;
using System.ComponentModel;

namespace TheLogWatcher
{
    class FileOpenManager
    {
        public FileOpenManager(Dictionary<MessageTypes, List<LogEntry>> data)
        {
            this.data = data;
        }

        private static Settings sets = Settings.Default;

        private Dictionary<MessageTypes, List<LogEntry>> data;

        public Dictionary<MessageTypes, List<LogEntry>> Data
        {
            get { return data; }
            set { data = value; }
        }

        /// <summary>
        ///     Checks if selected file is currently open.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="filename"></param>
        /// <returns>true if file is currently open</returns>
        private bool loadAlreadyOpen(string filename)
        {
            if (this.Data != null && this.Data.Count > 0 && filename.Equals(sets.History[0], StringComparison.CurrentCultureIgnoreCase))
            {
                DialogResult result = MessageBox.Show("This log file is currently opened.\nLoad anyway ?", "Already Opened", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
                if (result == DialogResult.Cancel)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        ///     This method is called once when opening a file.
        /// </summary>
        /// <param name="filename"></param>
        public DataAccess OpenFileFirstTime(string filename)
        {
            DataAccess dataAccess = null;
            bool loadFile = loadAlreadyOpen(filename);
            if (loadFile)
            {
                dataAccess = analyzeBestMethod(filename);

                if (dataAccess == null)
                {
                    Console.WriteLine("No DataAccess object !");
                    MessageBox.Show("File doesn't exist. History entry will be removed.", "Missing file", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return null;
                }

                // #######################

                AccessFileHandler fileHandler = new AccessFileHandler(filename);
                switch (dataAccess.FileHandle)
                {
                    case DataAccess.FileHandling.SingleFileHandling:
                        fileHandler.prepareSingleFileHandling();
                        break;
                    case DataAccess.FileHandling.MultiFileHandling:
                        fileHandler.prepareMultiFileHandling();
                        break;
                    default:
                        // ERROR
                        break;
                }
                LogFileProvider fnProvider = fileHandler.FnProvider;
                if (fnProvider == null)
                {
                    Console.WriteLine("Something wrong. No FileNameProvider.");
                    return null;
                }
                dataAccess.FnProvider = fnProvider;

                // #######################

                AccessDataHandler dataHandler = new AccessDataHandler(dataAccess);
                switch (dataAccess.DataHandle)
                {
                    case DataAccess.DataHandling.DataBuffering:
                        dataHandler.prepareDataBuffering();
                        break;
                    case DataAccess.DataHandling.LineIndexing:
                        dataHandler.prepareLineIndexing();
                        break;
                    default:
                        // ERROR
                        break;
                }
                //dataAccess.LineIndexes = dataHandler.LineIndexes;
            }

            // Reply the filled data access object
            return dataAccess;
        }

        /// <summary>
        ///     Analyze the best data access method for the given file.
        ///     Compares this method to the configured standard setting and
        ///     gives feedback to the user (TODO).
        /// </summary>
        /// <param name="filename"></param>
        private DataAccess analyzeBestMethod(string filename)
        {
            FileInfo fileInfo = new FileInfo(filename);

            if (!fileInfo.Exists)
            {
                return null;
            }
            long fileLength = fileInfo.Length;

            // TODO: Differ between sizes

            //if (sets.FileHandling == DataAccess.FileHandling.SingleFileHandling)
            //{
            //    DataAccess.FileHandling fileHandle1 = (DataAccess.FileHandling)Enum.ToObject(typeof(DataAccess.FileHandling), 0);
            //    DataAccess.FileHandling fileHandle2 = (DataAccess.FileHandling)Enum.ToObject(typeof(DataAccess.FileHandling), 1);
            //}

            if (sets.HandleFileHandling == (int)DataAccess.FileHandling.SingleFileHandling &&
                sets.HandleDataManagement == (int)DataAccess.DataHandling.DataBuffering &&
                sets.HandleReadMethod == (int)DataAccess.ReaderHandling.ReadFull)
            {
                long myMaxValue = 10000000L;
                if (fileLength > myMaxValue)
                {
                    // TODO: Warning for user that current method is ineffective
                }
            }

            DataAccess accessMethod = new DataAccess();
            accessMethod.FileHandle = (DataAccess.FileHandling)Enum.ToObject(typeof(DataAccess.FileHandling), sets.HandleFileHandling);
            accessMethod.DataHandle = (DataAccess.DataHandling)Enum.ToObject(typeof(DataAccess.DataHandling), sets.HandleDataManagement);
            accessMethod.ReaderHandle = (DataAccess.ReaderHandling)Enum.ToObject(typeof(DataAccess.ReaderHandling), sets.HandleReadMethod);

            return accessMethod;
        }
    }
}
